﻿using System;
using System.ComponentModel;

namespace TelecoSystems.Infrastructure.Helpers
{

    public abstract class PagedViewModelBase : ViewModelBase, IPagedCollectionView
    {
        private static PropertyChangedEventArgs IsPageChangingChangedEventArgs = new PropertyChangedEventArgs("IsPageChanging");
        private static PropertyChangedEventArgs ItemCountChangedEventArgs = new PropertyChangedEventArgs("ItemCount");
        private static PropertyChangedEventArgs PageIndexChangedEventArgs = new PropertyChangedEventArgs("PageIndex");
        private static PropertyChangedEventArgs PageSizeChangedEventArgs = new PropertyChangedEventArgs("PageSize");
        private static PropertyChangedEventArgs TotalItemCountChangedEventArgs = new PropertyChangedEventArgs("TotalItemCount");
        private static PropertyChangedEventArgs IsLoadingChangedEventArgs = new PropertyChangedEventArgs("IsLoading");

        bool _isLoading;
        public bool IsLoading
        {
            get { return _isLoading; }
            set
            {
                if (_isLoading != value)
                {
                    _isLoading = value;
                    RaisePropertyChanged(IsLoadingChangedEventArgs);
                }
            }
        }


        #region IPagedCollectionView Members

        public bool CanChangePage
        {
            get { return true; }
        }

        bool isPageChanging;
        public bool IsPageChanging
        {
            get { return isPageChanging; }
            private set
            {
                if (isPageChanging != value)
                {
                    isPageChanging = value;
                    RaisePropertyChanged(IsPageChangingChangedEventArgs);
                }
            }
        }

        int itemCount;
        public int ItemCount
        {
            get { return itemCount; }
            set
            {
                if (itemCount != value)
                {
                    itemCount = value;
                    RaisePropertyChanged(ItemCountChangedEventArgs);
                }
            }
        }

        public bool MoveToFirstPage()
        {
            return MoveToPage(0);
        }

        public bool MoveToLastPage()
        {
            return MoveToPage(TotalItemCount / PageSize);
        }

        public bool MoveToNextPage()
        {
            return MoveToPage(PageIndex + 1);
        }

        public abstract void LoadData();

        public bool MoveToPage(int index)
        {
            if (index == PageIndex || index < 0 || index > TotalItemCount / PageSize)
            {
                return false;
            }

            PageChangingEventArgs args = new PageChangingEventArgs(index);

            try
            {
                IsPageChanging = true;
                PageChanging(this, args);

                if (!args.Cancel)
                {
                    pageIndex = index;
                    LoadData();

                    RaisePropertyChanged(PageIndexChangedEventArgs);
                    PageChanged(this, EventArgs.Empty);

                    return true;
                }

                return false;
            }
            finally
            {
                IsPageChanging = false;
            }
        }

        public bool MoveToPreviousPage()
        {
            return MoveToPage(PageIndex - 1);
        }

        public event EventHandler<EventArgs> PageChanged = delegate { };
        public event EventHandler<PageChangingEventArgs> PageChanging = delegate { };

        int pageIndex;
        public int PageIndex
        {
            get { return pageIndex; }
            set
            {
                if (pageIndex < 0 || pageIndex > totalItemCount / PageSize)
                {
                    throw new ArgumentOutOfRangeException("PageIndex must be greater than or equal to 0 and less than the page count");
                }

                MoveToPage(value);
            }
        }

        int pageSize = 10;// default page size to 10
        public int PageSize
        {
            get { return pageSize; }
            set
            {
                if (pageSize != value)
                {
                    pageSize = value;
                    RaisePropertyChanged(PageSizeChangedEventArgs);
                }
            }
        }

        int totalItemCount;
        public int TotalItemCount
        {
            get { return totalItemCount; }
            set
            {
                if (totalItemCount != value)
                {
                    totalItemCount = value;
                    RaisePropertyChanged(TotalItemCountChangedEventArgs);
                }
            }
        }

        #endregion
    }


}
